package qc.module.ehs.api.controller;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import qc.common.core.constants.QCAuthConstant;
import qc.common.core.enums.EhsHazardPreventTypeEnum;
import qc.common.core.enums.EhsRiskLevelEnum;
import qc.common.core.enums.TimeRangeLengthEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.pair.KeyValuePairDto;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.IdentifierUtil;
import qc.module.ehs.dto.hazard.*;
import qc.module.ehs.dto.org.EhsOrgDto;
import qc.module.ehs.dto.templatehazard.TplHazardCategoryDto;
import qc.module.ehs.dto.templatehazard.TplHazardItemDto;
import qc.module.ehs.dto.templatehazard.TplHazardProjectDto;
import qc.module.ehs.dto.unit.EhsUnitDto;
import qc.module.ehs.entity.*;
import qc.module.ehs.service.*;
import qc.module.platform.dto.dept.DeptSimpleDto;
import qc.module.platform.dto.uac.UacUserInfoDto;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * HazardController
 *
 * @author QuCheng Tech
 * @create 2024/6/13
 */
@RestController
@RequestMapping("/hazard")
public class HazardController {
    
    @Autowired
    private EhsUnitIdentificationRecordService unitIdentificationRecordService;

    @Autowired
    HttpServletRequest request;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;
    
    @Autowired
    private EhsTplHazarditemService hazarditemService;
    
    @Autowired
    private EhsTplHazardprojectService hazardprojectService;
    
    @Autowired
    private EhsTplHazardcategoryService hazardcategoryService;
    
    @Autowired
    private EhsUnitBasicService unitBasicService;
    
    @Autowired
    private EhsUnitLateststatusService unitLateststatusService;
    
    @Autowired
    private EhsHazardBasicService hazardBasicService;
    
    @Autowired
    private EhsHazardPreventrecordService hazardPreventrecordService;

    @Autowired
    private EhsHazardLateststatusService hazardLateststatusService;

    @Autowired
    private EhsOrgService orgService;

    @Autowired
    private OrgController orgController;
    
    //时间范围类型；默认按月
    private final Integer TIME_RANGE = TimeRangeLengthEnum.MONTH.getIndex();
    
    /**
     * 按单元查询危险源
     * 
     * @param condition 查询条件
     * @return QueryHazardByUnitResultDto
     * @author QuCheng Tech
     * @since 2024/6/14
     */
    @RequestMapping(value = "/byunit",method = {RequestMethod.GET,RequestMethod.POST})
    public QueryHazardByUnitResultDto queryByUnit(@RequestBody QueryHazardByUnitConditionDto condition) throws QCPromptException {
        //获取当前用户所属部门ID集合
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        List<DeptSimpleDto> depts = getUserValidDepts(token);
        if (CollectionUtils.isEmpty(depts)) throw new QCPromptException("当前用户无有效项目部门信息");
        List<Integer> deptIds = depts.stream().map(DeptSimpleDto::getId).collect(Collectors.toList());
        
        return unitIdentificationRecordService.queryByUnit(condition,deptIds);
    }

    /**
     * 指定单元查询指定周期危险源
     * 
     * @param condition 查询条件
     * @return QueryOneUnitHazardResultDto
     * @author QuCheng Tech
     * @since 2024/7/3
     * @description 获取指定单元的指定周期的危险源清单；在指定的周期内未对该单元进行危险源辨识时危险源清单为空；
     *              指定周期为指定的1个代表该周期的时间点，至多有1条该单元的辨识记录；
     */
    @RequestMapping(value = "/oneunit",method = {RequestMethod.GET,RequestMethod.POST})
    public QueryOneUnitHazardResultDto getOneUnit(@RequestBody QueryOneUnitHazardConditionDto condition) throws QCPromptException, ParseException {
        return unitIdentificationRecordService.getOneUnit(condition,null);
    }

    /**
     * 指定单元全面辨识危险源
     * 
     * @param condition 全面辨识条件
     * @return QueryOneUnitHazardResultDto
     * @author QuCheng Tech
     * @since 2024/6/28
     * @description 对指定的单元使用指定的导则库进行全面辨识输入信息；对指定单元和指定辨识周期的危险源辨识记录进行替换更新，
     *              对照使用的导则库添加所有危险源，初始化辨识结果；
     */
    @RequestMapping(value = "/overall",method = {RequestMethod.GET,RequestMethod.POST})
    public QueryOneUnitHazardResultDto identificationOverAll(@RequestBody HazardOverAllIdentificationDto condition) throws QCPromptException, ParseException {
        //获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);
        
        //1.条件判空
        if (condition == null) throw new QCPromptException("条件对象不能为空");
        if (StringUtils.isBlank(condition.getUnitcode())) throw new QCPromptException("单元ID不能为空");
        //if (condition.getTmtype() == null) throw new QCPromptException("时间范围类型不能为空");
        if (StringUtils.isBlank(condition.getBegintm())) throw new QCPromptException("辨识周期起始时间不能为空");
        if (StringUtils.isBlank(condition.getEndtm())) throw new QCPromptException("辨识周期截止时间不能为空");
        if (StringUtils.isBlank(condition.getHdbcd())) throw new QCPromptException("导则库编码不能为空");
        if (condition.getHicds() == null || condition.getHicds().size() == 0x0) throw new QCPromptException("传入的危险源清单ID集合不能为空");
        
        //2.全面辨识危险源
        identificaitonAllHazard(condition,userInfo);
        
        //3.全面辨识完成后查询记录结果返回
        QueryOneUnitHazardConditionDto dto = new QueryOneUnitHazardConditionDto();
        dto.setUnitid(condition.getUnitcode());
        dto.setTmtype(condition.getTmtype());
        dto.setBegintm(condition.getBegintm());
        dto.setEndtm(condition.getEndtm());
        QueryOneUnitHazardResultDto resultDto = unitIdentificationRecordService.getOneUnit(dto,condition.getHdbcd());
        
        return resultDto;
    }

    /**
     * 全面辨识危险源
     * 
     * @param condition
     * @param userInfo 登录用户信息
     * @return
     * @throws QCPromptException
     * @throws ParseException
     * @author QuCheng Tech
     * @since 2024/6/28
     */
    private String identificaitonAllHazard(HazardOverAllIdentificationDto condition,UacUserInfoDto userInfo) 
            throws QCPromptException, ParseException {

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (org.apache.commons.lang3.StringUtils.isNotBlank(condition.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }

        Date beginTime = beginDate;
        Date endTime = endDate;
        if (condition.getTmtype() == null) condition.setTmtype(TIME_RANGE);
        if (condition.getTmtype() == TimeRangeLengthEnum.MONTH.getIndex()){
            //按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }else if (condition.getTmtype() == TimeRangeLengthEnum.QUARTER.getIndex()){
            //按季度：根据开始时间处理为开始时间所在季度的第一天，根据结束时间处理为结束时间所在季度最后一天
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x0, 0x1);
            int beginTimeMonth = DateUtil.getMonth(beginDate);
            if (beginTimeMonth >= 10)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x9, 0x1);
            else if (beginTimeMonth >= 7)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x6, 0x1);
            else if (beginTimeMonth >= 4)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x3, 0x1);

            //先计算结束时间所在季度的开始时间endtmbegin，再根据endtmbegin计算结束时间
            Date endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x0, 0x1);
            int endTimeMonth = DateUtil.getMonth(endDate);
            if (endTimeMonth >= 10)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x9, 0x1);
            else if (endTimeMonth >= 7)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x6, 0x1);
            else if (endTimeMonth >= 4)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x3, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endtmbegin, 0x3), -1);
        }else{
            //默认按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }

        //获取指定单元指定周期单元危险源辨识记录
        EhsUnitIdentificationRecord unitIdentificationRecord = unitIdentificationRecordService
                .getUnitTmRecord(condition.getUnitcode(),condition.getBegintm(), condition.getEndtm(),condition.getTmtype());
        //单元危险源辨识记录ID，单元危险源辨识记录信息数量计数
        String identificationId = "";
        boolean unitIdentificationRecordIsExist = false;//记录是否存在
        Integer general1 = 0x0,major1 = 0x0,level11 = 0x0,level12 = 0x0,level13 = 0x0,level14 = 0x0,
                general2 = 0x0,major2 = 0x0,level21 = 0x0,level22 = 0x0,level23 = 0x0,level24 = 0x0;
        if (Objects.isNull(unitIdentificationRecord)){
            //无记录
            identificationId = IdentifierUtil.randomUUID();
            unitIdentificationRecordIsExist = false;
            unitIdentificationRecord = new EhsUnitIdentificationRecord();

            unitIdentificationRecord.setRecordid(identificationId);
            unitIdentificationRecord.setUnitid(condition.getUnitcode());
            unitIdentificationRecord.setTmtype(condition.getTmtype());
            unitIdentificationRecord.setTmbegin(beginTime);
            unitIdentificationRecord.setTmend(endTime);
            if (StringUtils.isBlank(condition.getTmstr())) unitIdentificationRecord.setTmstr("");
            else unitIdentificationRecord.setTmstr(condition.getTmstr());
            unitIdentificationRecord.setFlag(false);//全面辨识时状态设置为false辨识中
            unitIdentificationRecord.setUpdatetm(new Date());
            unitIdentificationRecord.setUpdateuser(userInfo.getName());
        }else{
            //有记录
            unitIdentificationRecordIsExist = true;
            identificationId = unitIdentificationRecord.getRecordid();
            general1 = unitIdentificationRecord.getGeneral1();
            major1 = unitIdentificationRecord.getMajor1();
            level11 = unitIdentificationRecord.getLevel11();
            level12 = unitIdentificationRecord.getLevel12();
            level13 = unitIdentificationRecord.getLevel13();
            level14 = unitIdentificationRecord.getLevel14();
            general2 = unitIdentificationRecord.getGeneral2();
            major2 = unitIdentificationRecord.getMajor2();
            level21 = unitIdentificationRecord.getLevel21();
            level22 = unitIdentificationRecord.getLevel22();
            level23 = unitIdentificationRecord.getLevel23();
            level24 = unitIdentificationRecord.getLevel24();
        }

        //1.全面辨识危险源之前，先清空指定危险源指定辨识周期起始时间的辨识记录，指定危险源最新状态信息，指定单元指定周期单元危险源辨识记录信息
        //1.1 根据单元ID查询危险源基础信息，获取所有危险源ID集合
        List<EhsHazardBasicDto> hazardBasicDtos = hazardBasicService.getByUnitId(condition.getUnitcode());
        if (CollectionUtils.isNotEmpty(hazardBasicDtos)){
            List<String> hazardIds = hazardBasicDtos.stream().map(EhsHazardBasicDto::getHazardid).collect(Collectors.toList());
            //先统计需要删除的记录中的各个数量
            //查询已有的指定危险源、指定周期的危险源辨识记录
            List<EhsHazardPreventrecord> oldIdentifications = hazardPreventrecordService.getRecords(hazardIds,
                    EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex(), beginTime,endTime,condition.getTmtype());
            if (CollectionUtils.isNotEmpty(oldIdentifications)){
                for (EhsHazardPreventrecord oldIdentification : oldIdentifications){
                    if (oldIdentification.getConafterhazardcategory() == 3){
                        //原有记录为第一类危险源
                        if (oldIdentification.getConafterismajor()) major1 -= 0x1;
                        else general1 -= 0x1;
                    }else if (oldIdentification.getConafterhazardcategory() == 4){
                       //原有记录为第二类危险源 
                        if (oldIdentification.getConafterismajor()) major2 -= 0x1;
                        else general2 -= 0x1;
                    }else {
                        //不处理
                    }
                    
                    //查询指定危险源指定周期的危险源风险评价记录，根据辨识记录的辨识结论判断当前危险源为第一类危险源还是第二类危险源，
                    // 再根据原记录风险等级分别统计风险等级数量 - 1
                    EhsHazardPreventrecord oldEvaluation = hazardPreventrecordService.getOneRecord(oldIdentification.getHazardid(),
                            EhsHazardPreventTypeEnum.EVALUATION.getIndex(), beginTime,endTime,condition.getTmtype());
                    if (Objects.nonNull(oldEvaluation)){
                        if (oldIdentification.getConafterhazardcategory() == 3){
                            //第一类危险源
                            if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.LOW.getIndex()) level11 -= 0x1;
                            else if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.GENERAL.getIndex()) level12 -= 0x1;
                            else if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.GREATER.getIndex()) level13 -= 0x1;
                            else if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.MAJOR.getIndex()) level14 -= 0x1;
                        }else if (oldIdentification.getConafterhazardcategory() == 4){
                            //第二类危险源
                            if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.LOW.getIndex()) level21 -= 0x1;
                            else if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.GENERAL.getIndex()) level22 -= 0x1;
                            else if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.GREATER.getIndex()) level23 -= 0x1;
                            else if (oldEvaluation.getConafterrisklevel() == EhsRiskLevelEnum.MAJOR.getIndex()) level24 -= 0x1;
                        }else {
                            //不适用/不存在
                        }
                    }
                    
                }
            }
            
            for (EhsHazardBasicDto dto : hazardBasicDtos){
                //1.1.1 根据危险源ID、辨识周期时间删除危险源辨识记录
                hazardPreventrecordService.deleteRecords(dto.getHazardid(),EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex(),
                        beginTime,endTime,condition.getTmtype());
                //1.1.2 根据危险源ID、辨识周期时间删除危险源风险评价记录
                hazardPreventrecordService.deleteRecords(dto.getHazardid(),EhsHazardPreventTypeEnum.EVALUATION.getIndex(),
                        beginTime,endTime,condition.getTmtype());
                //1.1.3 根据危险源ID删除危险源最新状态
                hazardLateststatusService.deleteHazardLatestStatus(dto.getHazardid());
            }
        }
        
        //2.全面辨识危险源
        //2.1 根据导则库编码获取所有危险源清单集合
        List<TplHazardItemDto> itemDtos = hazarditemService.getHdbcdItems(condition.getHdbcd());

        //2.2 定义需要新增的各表信息集合
        List<EhsHazardBasicDto> hazardBasics = new ArrayList<>();//危险源基础信息集合
        List<EhsHazardPreventrecord> hazardPreventrecords = new ArrayList<>();//危险源辨识信息集合
        List<EhsHazardLateststatus> hazardLateststatuses = new ArrayList<>();//危险源最新状态信息集合
        
        //2.3 全面辨识危险源
        if (CollectionUtils.isNotEmpty(itemDtos)){
            //2.3.1 获取指定单元信息，用于设置危险源属性信息
            EhsUnitDto unitDto = unitBasicService.get(condition.getUnitcode());
            
            for (TplHazardItemDto itemDto : itemDtos){
                //2.3.2 判断危险源清单ID在指定单元危险源基础信息中是否存在，不存在则将清单添加为危险源基础信息
               //b.判断危险源清单是否已经在单元危险源基础信息中存在，不存在才添加为基础信息
                boolean hazardIsExist = false;
                String hazardId = "";
                if (hazardBasicDtos != null) {
                    for (EhsHazardBasicDto basicDto : hazardBasicDtos){
                        if (StringUtils.isNotBlank(basicDto.getItemcode())){
                            if (basicDto.getItemcode().equals(itemDto.getHicd())){
                                hazardIsExist = true;
                                hazardId = basicDto.getHazardid();
                            }
                        }
                    }
                }
                if (hazardId == "") hazardId = IdentifierUtil.randomUUID();
                if (!hazardIsExist){
                    //获取指定项目信息
                    TplHazardProjectDto projectDto = hazardprojectService.getProject(itemDto.getHpjtcd());
                    //获取指定类别信息
                    TplHazardCategoryDto categoryDto = hazardcategoryService.getCategory(projectDto.getHcatcd());
                    //危险源清单转换为危险源基础信息
                    EhsHazardBasicDto hazardBasic = new EhsHazardBasicDto();
                    hazardBasic.setHazardid(hazardId);
                    hazardBasic.setHazardname(itemDto.getHinm());
                    hazardBasic.setUnitcode(unitDto.getUnitid());
                    hazardBasic.setCategorycode(categoryDto.getHcatcd());
                    hazardBasic.setProjectcode(itemDto.getHpjtcd());
                    hazardBasic.setItemcode(itemDto.getHicd());
                    hazardBasic.setOrgcode(unitDto.getOrgcode());
                    hazardBasic.setIsreport(false);//是否上报默认false
                    hazardBasic.setUnitname(unitDto.getUnitname());
                    hazardBasic.setCategoryname(categoryDto.getHcatnm());
                    hazardBasic.setProjectname(projectDto.getHpjtnm());
                    hazardBasic.setItemname(itemDto.getHinm());
                    //TODO 危险源具体位置设置 hazardBasic.setPosition();
                    hazardBasic.setIsmajor(itemDto.getIsmajor());
                    hazardBasic.setCouse(itemDto.getCause());
                    hazardBasics.add(hazardBasic);
                }

                /*2.3.3 全面辨识危险源，添加危险源辨识记录信息：
                    危险源清单在传入的危险源清单集合中不存在的危险源添加辨识记录为不适用，
                    传入的危险源清单集合中存在的危险源添加记录为存在（先默认为危险源存在，如不存在则由人工进行修改）
                */
                boolean isExist = condition.getHicds().stream().filter(p -> p.equals(itemDto.getHicd())).findAny().isPresent();
                EhsHazardPreventrecord hazardPreventrecord = new EhsHazardPreventrecord();
                hazardPreventrecord.setRecordid(IdentifierUtil.randomUUID());
                hazardPreventrecord.setHazardid(hazardId);
                hazardPreventrecord.setType(EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex());
                hazardPreventrecord.setTmtype(condition.getTmtype());
                hazardPreventrecord.setTmbegin(beginTime);
                hazardPreventrecord.setTmend(endTime);
                hazardPreventrecord.setIdentificationid(identificationId);
                hazardPreventrecord.setMaycouseharm(itemDto.getConsequence());
                hazardPreventrecord.setConafterismajor(itemDto.getIsmajor());
                hazardPreventrecord.setUndercontrol(true);//防控措施是否有效，默认true
                if (isExist){
                    //存在：辨识结果:3-第一类危险源
                    hazardPreventrecord.setDescription(itemDto.getDescription());
                    hazardPreventrecord.setConafterhazardcategory(3);
                }else {
                    //不存在：辨识结果：1-不适用
                    hazardPreventrecord.setConafterhazardcategory(1);
                }
                //全面辨识时默认统计为第一类危险源
                if (itemDto.getIsmajor()){
                    //重大危险源
                    hazardPreventrecord.setConafterrisklevel(EhsRiskLevelEnum.GREATER.getIndex());
                    if (isExist) major1 += 0x1; //危险源存在才统计
                }else {
                    //一般危险源
                    hazardPreventrecord.setConafterrisklevel(EhsRiskLevelEnum.LOW.getIndex());
                    if (isExist) general1 += 0x1;
                }
                hazardPreventrecord.setIntm(new Date());
                hazardPreventrecord.setInuser(userInfo.getName());
                hazardPreventrecords.add(hazardPreventrecord);

                //2.3.4 添加危险源最新状态信息
                EhsHazardLateststatus hazardLateststatus = new EhsHazardLateststatus();
                hazardLateststatus.setHazardid(hazardId);
                hazardLateststatus.setRecentidentificationtm(new Date());
                hazardLateststatus.setDescription(itemDto.getDescription());
                hazardLateststatus.setMaycouseharm(itemDto.getConsequence());
                hazardLateststatus.setIsmajor(hazardPreventrecord.getConafterismajor());
                hazardLateststatus.setHazardcategory(hazardPreventrecord.getConafterhazardcategory());
                hazardLateststatus.setRisklevel(hazardPreventrecord.getConafterrisklevel());
                hazardLateststatuses.add(hazardLateststatus);
            }
            //2.3.5 设置单元危险源辨识记录信息
            unitIdentificationRecord.setGeneral1(general1);
            unitIdentificationRecord.setMajor1(major1);
            unitIdentificationRecord.setLevel11(level11);
            unitIdentificationRecord.setLevel12(level12);
            unitIdentificationRecord.setLevel13(level13);
            unitIdentificationRecord.setLevel14(level14);
            unitIdentificationRecord.setGeneral2(general2);
            unitIdentificationRecord.setMajor2(major2);
            unitIdentificationRecord.setLevel21(level21);
            unitIdentificationRecord.setLevel22(level22);
            unitIdentificationRecord.setLevel23(level23);
            unitIdentificationRecord.setLevel24(level24);
        }

        //2.4 全面辨识相关各表数据新增/更新
        //2.4.1 新增危险源基础信息
        if (CollectionUtils.isNotEmpty(hazardBasics)){
            for (EhsHazardBasicDto dto : hazardBasics){
                hazardBasicService.addHazardBasic(dto);
            }
        }
        //2.4.2 新增危险源辨识信息
        if (CollectionUtils.isNotEmpty(hazardPreventrecords)){
            for (EhsHazardPreventrecord preventrecord : hazardPreventrecords){
                hazardPreventrecordService.addRecord(preventrecord);
            }
        }
        //2.4.3 新增危险源最新状态信息
        if (CollectionUtils.isNotEmpty(hazardLateststatuses)){
            for (EhsHazardLateststatus hazardLateststatus : hazardLateststatuses){
                hazardLateststatusService.addHazardLatestStatus(hazardLateststatus);
            }
        }
        //2.4.4 新增/更新单元危险源辨识记录信息
        if (unitIdentificationRecordIsExist){
            //更新
            unitIdentificationRecordService.updateRecord(unitIdentificationRecord);
        }else {
            //新增
             unitIdentificationRecordService.addRecord(unitIdentificationRecord);
        }

        //2.4.5 更新/新增单元最新状态信息
        addOrUpdateUnitLatestStatus(condition.getUnitcode());
        
        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取指定危险源基础信息 - 同时支持@RequestParam与@PathVariable方式
     *  
     * @param id 危险源ID
     * @return EhsHazardBasicDto
     * @author QuCheng Tech
     * @since 2024/7/3
     */
    @GetMapping("/basic")
    public EhsHazardBasicDto getHazardBasicInfoByParam(@RequestParam String id) throws QCPromptException {
        return hazardBasicService.getHazardBasicInfo(id);
    }

    /**
     * 获取指定危险源基础信息 - 同时支持@RequestParam与@PathVariable方式
     *
     * @param id 危险源ID
     * @return EhsHazardBasicDto
     * @author QuCheng Tech
     * @since 2024/7/3
     */
    @GetMapping("/basic/id")
    public EhsHazardBasicDto getHazardBasicInfoByPath(@PathVariable String id) throws QCPromptException {
        return hazardBasicService.getHazardBasicInfo(id);
    }

    /**
     * 获取指定危险源完整信息
     *
     * @param condition 查询条件
     * @return EhsHazardFullInfoDto
     * @author QuCheng Tech
     * @since 2024/7/3
     */
    @RequestMapping(value = "/full",method = {RequestMethod.GET,RequestMethod.POST})
    public EhsHazardFullInfoDto getFullInfo(@RequestBody EhsHazardFullInfoConditionDto condition) throws QCPromptException {
        return hazardBasicService.getFullInfo(condition);
    }

    /**
     * 辨识指定危险源
     * 
     * @param dto 辨识信息
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/7/3
     * @description 保存指定危险源的辨识结果
     */
    @RequestMapping(value = "/identification",method = {RequestMethod.GET,RequestMethod.POST})
    public String identification(@RequestBody HazardIdentificationDto dto) throws QCPromptException, ParseException {
        //1.请求参数判空
        if (dto == null) return QCUnifyReturnValue.Warn("请求对象不能为空");

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (org.apache.commons.lang3.StringUtils.isNotBlank(dto.getTmbegin())) {
            try {
                beginDate = DateUtil.parseDate(dto.getTmbegin());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("条件中的开始日期转换错误");
            }
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(dto.getTmend())) {
            try {
                endDate = DateUtil.parseDate(dto.getTmend());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("条件中的截止日期转换错误");
            }
        }
        
        Date beginTime = beginDate;
        Date endTime = endDate;
        if (dto.getTmtype() == null) dto.setTmtype(TIME_RANGE);
        if (dto.getTmtype() == TimeRangeLengthEnum.MONTH.getIndex()){
            //按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }else if (dto.getTmtype() == TimeRangeLengthEnum.QUARTER.getIndex()){
            //按季度：根据开始时间处理为开始时间所在季度的第一天，根据结束时间处理为结束时间所在季度最后一天
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x0, 0x1);
            int beginTimeMonth = DateUtil.getMonth(beginDate);
            if (beginTimeMonth >= 10)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x9, 0x1);
            else if (beginTimeMonth >= 7)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x6, 0x1);
            else if (beginTimeMonth >= 4)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x3, 0x1);

            //先计算结束时间所在季度的开始时间endtmbegin，再根据endtmbegin计算结束时间
            Date endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x0, 0x1);
            int endTimeMonth = DateUtil.getMonth(endDate);
            if (endTimeMonth >= 10)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x9, 0x1);
            else if (endTimeMonth >= 7)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x6, 0x1);
            else if (endTimeMonth >= 4)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x3, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endtmbegin, 0x3), -1);
        }else{
            //默认按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }

        //2.获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        //3.获取指定单元信息
        EhsUnitDto unitDto = unitBasicService.get(dto.getSubunitcode());

        //4.获取指定单元指定周期单元危险源辨识记录
        EhsUnitIdentificationRecord unitIdentificationRecord = unitIdentificationRecordService
                .getUnitTmRecord(dto.getSubunitcode(),dto.getTmbegin(), dto.getTmend(),dto.getTmtype());
        //4.1 记录单元危险源辨识记录ID，单元危险源辨识记录信息数量计数
        String identificationId = "";
        boolean unitIdentificationRecordIsExist = false;//记录是否存在
        Integer general1 = 0x0,major1 = 0x0,level11 = 0x0,level12 = 0x0,level13 = 0x0,level14 = 0x0,
                general2 = 0x0,major2 = 0x0,level21 = 0x0,level22 = 0x0,level23 = 0x0,level24 = 0x0;
        //4.2 判断单元危险源辨识记录是否存在，存在则记录各统计数量，否则设置相关属性值
        if (Objects.isNull(unitIdentificationRecord)){
            //无记录
            identificationId = IdentifierUtil.randomUUID();
            unitIdentificationRecordIsExist = false;
            unitIdentificationRecord = new EhsUnitIdentificationRecord();

            unitIdentificationRecord.setRecordid(identificationId);
            unitIdentificationRecord.setUnitid(dto.getSubunitcode());
            unitIdentificationRecord.setTmtype(dto.getTmtype());
            unitIdentificationRecord.setTmbegin(beginTime);
            unitIdentificationRecord.setTmend(endTime);
            unitIdentificationRecord.setTmstr(dto.getTmstr());
            unitIdentificationRecord.setFlag(false);//辨识时状态设置为false辨识中
            unitIdentificationRecord.setUpdatetm(new Date());
            unitIdentificationRecord.setUpdateuser(userInfo.getName());
        }else{
            //有记录
            unitIdentificationRecordIsExist = true;
            identificationId = unitIdentificationRecord.getRecordid();
            general1 = unitIdentificationRecord.getGeneral1();
            major1 = unitIdentificationRecord.getMajor1();
            level11 = unitIdentificationRecord.getLevel11();
            level12 = unitIdentificationRecord.getLevel12();
            level13 = unitIdentificationRecord.getLevel13();
            level14 = unitIdentificationRecord.getLevel14();
            general2 = unitIdentificationRecord.getGeneral2();
            major2 = unitIdentificationRecord.getMajor2();
            level21 = unitIdentificationRecord.getLevel21();
            level22 = unitIdentificationRecord.getLevel22();
            level23 = unitIdentificationRecord.getLevel23();
            level24 = unitIdentificationRecord.getLevel24();
        }
        
        //危险源ID
        String hazardId = "";
        //5.判断请求参数中危险源ID是否为空，如果为空则是新增危险源，否则为辨识危险源
        if (StringUtils.isBlank(dto.getHazardid())){
            //新增危险源时
            //5.1 判断危险源是否已经存在，不存在则添加为危险源基础信息
            EhsHazardBasicDto basicDto = hazardBasicService.getHazard(dto.getSubunitcode(),
                    dto.getHazardname(),dto.getCategoryname(),dto.getProjectname());
            if (Objects.isNull(basicDto)){
                hazardId = IdentifierUtil.randomUUID();
                basicDto = new EhsHazardBasicDto();
                basicDto.setHazardid(hazardId);
                basicDto.setHazardname(dto.getHazardname());
                basicDto.setUnitcode(dto.getSubunitcode());
                basicDto.setUnitname(unitDto.getUnitname());
                basicDto.setOrgcode(unitDto.getOrgcode());
                basicDto.setIsreport(false);
                basicDto.setCategoryname(dto.getCategoryname());
                basicDto.setProjectname(dto.getProjectname());
                basicDto.setPosition(dto.getPosition());
                basicDto.setIsmajor(dto.getIsmajor());
                basicDto.setCouse(dto.getCouse());
                //添加危险源基础信息
                hazardBasicService.addHazardBasic(basicDto);
            }else{
                hazardId = basicDto.getHazardid();
                //如果具体部位不为空，设置并修改修改基础信息
                basicDto.setPosition(dto.getPosition());
                hazardBasicService.updateHazardBasic(basicDto);
            }
        } else{
            //辨识危险源时
            hazardId = dto.getHazardid();
            //获取指定危险源
            EhsHazardBasicDto basicDto = hazardBasicService.getHazardBasicInfo(hazardId);
            //如果具体部位不为空，设置并修改修改基础信息
            basicDto.setPosition(dto.getPosition());
            hazardBasicService.updateHazardBasic(basicDto);
        }
        
        //6.添加/更新危险源辨识信息，如果危险源已经存在则更新，同时统计单元危险源辨识记录数量，否则新增
        //6.1 获取指定危险源指定周期辨识记录，判断记录存在则更新，否则添加
        EhsHazardPreventrecord identification = hazardPreventrecordService.getOneRecord(hazardId,
                EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex(), beginTime, endTime,dto.getTmtype());
        boolean identificationIsExist = false;
        if (Objects.isNull(identification)){
            //无记录，新增辨识记录
            identificationIsExist = false;
            identification = new EhsHazardPreventrecord();
            identification.setHazardid(hazardId);
            identification.setType(EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex());
            identification.setTmtype(dto.getTmtype());
            identification.setTmbegin(beginTime);
            identification.setTmend(endTime);
        }else{
            //有记录，更新辨识记录
            identificationIsExist = true;
            //根据原辨识记录的辨识结论判断当前危险源为第一类危险源还是第二类危险源，再统计一般/重大数量：原数量 - 1
            if (identification.getConafterhazardcategory() == 3){
                //原记录为第一类危险源
                if (identification.getConafterismajor()) major1 -= 0x1;
                else general1 -= 0x1;
            }else if (identification.getConafterhazardcategory() == 4){
                //原记录为第二类危险源
                if (identification.getConafterismajor()) major2 -= 0x1;
                else general2 -= 0x1;
            }else {
                //不适用/不存在
            }
        }
        identification.setIdentificationid(unitIdentificationRecord.getRecordid());
        identification.setCondeptname(dto.getByuser());
        identification.setDescription(dto.getDescription());
        //identification.setResultormethod(dto.getResult());
        identification.setUndercontrol(dto.getUndercontrol());
        identification.setUnsafefactor(dto.getUnsafefactor());
        identification.setConafterhazardcategory(dto.getFinalresult());
        identification.setIntm(new Date());
        identification.setInuser(userInfo.getName());
        identification.setConafterismajor(dto.getIsmajor());
        if (identificationIsExist){
            //存在更新
            hazardPreventrecordService.updateRecord(identification,EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex());
        }else {
            //不存在新增
            hazardPreventrecordService.addRecord(identification);
        }
        
        //7.获取指定危险源最新状态信息，存在则更新，不存在则新增
        EhsHazardLateststatus hazardLateststatus = hazardLateststatusService.getByHazardId(hazardId);
        boolean hazardLateststatusIsExist = false;
        if (Objects.isNull(hazardLateststatus)){
            //无记录，新增
            hazardLateststatusIsExist = false;
            hazardLateststatus = new EhsHazardLateststatus();
            hazardLateststatus.setHazardid(hazardId);
        }else {
            //有记录，更新
            hazardLateststatusIsExist = true;
        }
        hazardLateststatus.setRecentidentificationtm(new Date());
        hazardLateststatus.setDescription(identification.getDescription());
        hazardLateststatus.setMaycouseharm(identification.getMaycouseharm());
        hazardLateststatus.setIsmajor(identification.getConafterismajor());
        hazardLateststatus.setHazardcategory(identification.getConafterhazardcategory());
        hazardLateststatus.setRisklevel(identification.getConafterrisklevel());
        if (hazardLateststatusIsExist){
            //不存在更新
            hazardLateststatusService.updateHazardLatestStatus(hazardLateststatus);
        }else {
            //存在新增
            hazardLateststatusService.addHazardLatestStatus(hazardLateststatus);
        }

        //8.根据辨识结论判断统计数量，新增辨识记录时数量统计+1
        if (dto.getFinalresult() == 3){
            //第一类危险源
            if (dto.getIsmajor()) major1 += 0x1;
            else general1 += 0x1;
        }else if (dto.getFinalresult() == 4){
            //第二类危险源
            if (dto.getIsmajor()) major2 += 0x1;
            else general2 += 0x1;
        }else {
            //不适用/不存在
        }

        //9.设置单元危险源辨识记录各统计数量信息，新增/更新单元危险源辨识记录
        unitIdentificationRecord.setGeneral1(general1);
        unitIdentificationRecord.setMajor1(major1);
        unitIdentificationRecord.setLevel11(level11);
        unitIdentificationRecord.setLevel12(level12);
        unitIdentificationRecord.setLevel13(level13);
        unitIdentificationRecord.setLevel14(level14);
        unitIdentificationRecord.setGeneral2(general2);
        unitIdentificationRecord.setMajor2(major2);
        unitIdentificationRecord.setLevel21(level21);
        unitIdentificationRecord.setLevel22(level22);
        unitIdentificationRecord.setLevel23(level23);
        unitIdentificationRecord.setLevel24(level24);
        //新增/更新单元危险源辨识记录信息
        if (unitIdentificationRecordIsExist){
            //存在更新
            unitIdentificationRecordService.updateRecord(unitIdentificationRecord);
        }else {
            //不存在新增
            unitIdentificationRecordService.addRecord(unitIdentificationRecord);
        }

        //10. 更新/新增单元最新状态信息
        addOrUpdateUnitLatestStatus(dto.getSubunitcode());
        
        //辨识结束后返回危险源ID
        return QCUnifyReturnValue.Success(hazardId);
    }


    /**
     * 评价指定危险源风险
     * 
     * @param dto 请求参数
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/7/3
     * @description 保存指定危险源的风险评价结果
     */
    @RequestMapping(value = "/evaluation",method = {RequestMethod.GET,RequestMethod.POST})
    public String evaluationRisk(@RequestBody HazardRiskEvaluationDto dto) throws ParseException, QCPromptException {
        //1.请求参数判空
        if (dto == null) return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getHazardid())) return QCUnifyReturnValue.Warn("危险源ID不能为空");

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (org.apache.commons.lang3.StringUtils.isNotBlank(dto.getTmbegin())) {
            try {
                beginDate = DateUtil.parseDate(dto.getTmbegin());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("条件中的开始日期转换错误");
            }
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(dto.getTmend())) {
            try {
                endDate = DateUtil.parseDate(dto.getTmend());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("条件中的截止日期转换错误");
            }
        }

        Date beginTime = beginDate;
        Date endTime = endDate;
        if (dto.getTmtype() == null) dto.setTmtype(TIME_RANGE);
        if (dto.getTmtype() == TimeRangeLengthEnum.MONTH.getIndex()){
            //按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }else if (dto.getTmtype() == TimeRangeLengthEnum.QUARTER.getIndex()){
            //按季度：根据开始时间处理为开始时间所在季度的第一天，根据结束时间处理为结束时间所在季度最后一天
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x0, 0x1);
            int beginTimeMonth = DateUtil.getMonth(beginDate);
            if (beginTimeMonth >= 10)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x9, 0x1);
            else if (beginTimeMonth >= 7)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x6, 0x1);
            else if (beginTimeMonth >= 4)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x3, 0x1);

            //先计算结束时间所在季度的开始时间endtmbegin，再根据endtmbegin计算结束时间
            Date endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x0, 0x1);
            int endTimeMonth = DateUtil.getMonth(endDate);
            if (endTimeMonth >= 10)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x9, 0x1);
            else if (endTimeMonth >= 7)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x6, 0x1);
            else if (endTimeMonth >= 4)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x3, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endtmbegin, 0x3), -1);
        }else{
            //默认按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }

        //2.获取用户信息
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        UacUserInfoDto userInfo = getUserInfo(token);

        //3.获取指定单元指定周期单元危险源辨识记录，各统计数量记录
        EhsUnitIdentificationRecord unitIdentificationRecord = unitIdentificationRecordService
                .getUnitTmRecord(dto.getSubunitcode(),dto.getTmbegin(), dto.getTmend(),dto.getTmtype());
        Integer general1 = unitIdentificationRecord.getGeneral1();
        Integer major1 = unitIdentificationRecord.getMajor1();
        Integer level11 = unitIdentificationRecord.getLevel11();
        Integer level12 = unitIdentificationRecord.getLevel12();
        Integer level13 = unitIdentificationRecord.getLevel13();
        Integer level14 = unitIdentificationRecord.getLevel14();
        Integer general2 = unitIdentificationRecord.getGeneral2();
        Integer major2 = unitIdentificationRecord.getMajor2();
        Integer level21 = unitIdentificationRecord.getLevel21();
        Integer level22 = unitIdentificationRecord.getLevel22();
        Integer level23 = unitIdentificationRecord.getLevel23();
        Integer level24 = unitIdentificationRecord.getLevel24();

        //4.获取指定危险源指定周期辨识记录，根据辨识结论判断
        EhsHazardPreventrecord identification = hazardPreventrecordService.getOneRecord(dto.getHazardid(),
                EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex(),beginTime,endTime,dto.getTmtype());
        
        //5.获取指定危险源指定周期评价记录，记录存在则更新，不存在则新增
        EhsHazardPreventrecord evaluation = hazardPreventrecordService.getOneRecord(dto.getHazardid(),
                EhsHazardPreventTypeEnum.EVALUATION.getIndex(),beginTime,endTime,dto.getTmtype());
        boolean evaluationIsExist = false;
        if (Objects.isNull(evaluation)){
            //无记录，新增风险评价记录
            evaluationIsExist = false;
            evaluation = new EhsHazardPreventrecord();
            evaluation.setHazardid(dto.getHazardid());
            evaluation.setType(EhsHazardPreventTypeEnum.EVALUATION.getIndex());
            evaluation.setTmtype(dto.getTmtype());
            evaluation.setTmbegin(beginTime);
            evaluation.setTmend(endTime);
            evaluation.setTmstr(dto.getTmstr());
            evaluation.setConinformation(dto.getContent());
        }else {
            //有记录，更新风险评价记录
            evaluationIsExist = true;
            //根据辨识记录的辨识结论判断当前危险源为第一类危险源还是第二类危险源，再根据原记录风险等级分别统计风险等级数量 - 1
            if (Objects.nonNull(identification)){
                if (identification.getConafterhazardcategory() == 3){
                    //第一类危险源
                    if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.LOW.getIndex()) level11 -= 0x1;
                    else if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.GENERAL.getIndex()) level12 -= 0x1;
                    else if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.GREATER.getIndex()) level13 -= 0x1;
                    else if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.MAJOR.getIndex()) level14 -= 0x1;
                }else if (identification.getConafterhazardcategory() == 4){
                    //第二类危险源
                    if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.LOW.getIndex()) level21 -= 0x1;
                    else if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.GENERAL.getIndex()) level22 -= 0x1;
                    else if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.GREATER.getIndex()) level23 -= 0x1;
                    else if (evaluation.getConafterrisklevel() == EhsRiskLevelEnum.MAJOR.getIndex()) level24 -= 0x1;
                }else {
                    //不适用/不存在
                }
            }
        }
        evaluation.setIdentificationid(unitIdentificationRecord.getRecordid());
        evaluation.setCondeptname(dto.getByuser());
        evaluation.setResultormethod(dto.getMethod());
        evaluation.setConafterrisklevel(dto.getRisklevel());
        evaluation.setConinformation(dto.getContent());
        evaluation.setInuser(userInfo.getName());
        evaluation.setIntm(new Date());
        if (evaluationIsExist){
            //存在更新
            hazardPreventrecordService.updateRecord(evaluation,EhsHazardPreventTypeEnum.EVALUATION.getIndex());
        }else {
            //不存在新增
            hazardPreventrecordService.addRecord(evaluation);
        }
        
        //6.获取指定危险源最新状态信息，设置风险等级并更新记录
        EhsHazardLateststatus hazardLateststatus = hazardLateststatusService.getByHazardId(dto.getHazardid());
        if (Objects.nonNull(hazardLateststatus)){
            hazardLateststatus.setRisklevel(dto.getRisklevel());
            hazardLateststatusService.updateHazardLatestStatus(hazardLateststatus);
        }
        
        //7.单元危险源辨识记录中各风险等级数量统计：根据风险等级计算相应风险等级数量，根据辨识结论判断统计第一类或第二类
        //7.1 根据辨识记录的辨识结论判断当前危险源为第一类危险源还是第二类危险源，再根据当前风险等级分别统计风险等级数量 + 1
        if (Objects.nonNull(identification)){
            if (identification.getConafterhazardcategory() == 3){
                //第一类危险源
                if (dto.getRisklevel() == EhsRiskLevelEnum.LOW.getIndex()) level11 += 0x1;
                else if (dto.getRisklevel() == EhsRiskLevelEnum.GENERAL.getIndex()) level12 += 0x1;
                else if (dto.getRisklevel() == EhsRiskLevelEnum.GREATER.getIndex()) level13 += 0x1;
                else if (dto.getRisklevel() == EhsRiskLevelEnum.MAJOR.getIndex()) level14 += 0x1;
            }else if (identification.getConafterhazardcategory() == 4){
                //第二类危险源
                if (dto.getRisklevel() == EhsRiskLevelEnum.LOW.getIndex()) level21 += 0x1;
                else if (dto.getRisklevel() == EhsRiskLevelEnum.GENERAL.getIndex()) level22 += 0x1;
                else if (dto.getRisklevel() == EhsRiskLevelEnum.GREATER.getIndex()) level23 += 0x1;
                else if (dto.getRisklevel() == EhsRiskLevelEnum.MAJOR.getIndex()) level24 += 0x1;
            }else {
                //不适用/不存在
            }
        }
        //7.2 设置单元危险源辨识记录各统计数量信息，更新单元危险源辨识记录
        unitIdentificationRecord.setGeneral1(general1);
        unitIdentificationRecord.setMajor1(major1);
        unitIdentificationRecord.setLevel11(level11);
        unitIdentificationRecord.setLevel12(level12);
        unitIdentificationRecord.setLevel13(level13);
        unitIdentificationRecord.setLevel14(level14);
        unitIdentificationRecord.setGeneral2(general2);
        unitIdentificationRecord.setMajor2(major2);
        unitIdentificationRecord.setLevel21(level21);
        unitIdentificationRecord.setLevel22(level22);
        unitIdentificationRecord.setLevel23(level23);
        unitIdentificationRecord.setLevel24(level24);
        unitIdentificationRecordService.updateRecord(unitIdentificationRecord);

        //8.更新/新增单元最新状态信息
        addOrUpdateUnitLatestStatus(dto.getSubunitcode());
        
        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取风险评价方法
     *
     * @return List<HazardRiskEvaluationMethodDto>
     * @author QuCheng Tech
     * @since 2024/7/5
     */
    @GetMapping("/evalmethods")
    public List<HazardRiskEvaluationMethodDto> getRiskEvaluationMethods(){
        List<HazardRiskEvaluationMethodDto> result = new ArrayList<>();

        //直接法
        HazardRiskEvaluationMethodDto method1 = new HazardRiskEvaluationMethodDto();
        method1.setMethod(1);
        method1.setName("直接法");
        method1.setOptions(new ArrayList<>());

        //LS法
        HazardRiskEvaluationMethodDto method2 = new HazardRiskEvaluationMethodDto();
        method2.setMethod(2);
        method2.setName("LS法");
        List<HazardRiskEvaluationOptionsItemDto> itemLS = new ArrayList<>();
        HazardRiskEvaluationOptionsItemDto lsItemL = new HazardRiskEvaluationOptionsItemDto();
        lsItemL.setCode("L");
        lsItemL.setName("L");
        List<KeyValuePairDto> lsItemLOptions = new ArrayList<>();
        KeyValuePairDto lsLKeyValue1 = new KeyValuePairDto();
        lsLKeyValue1.setKey("1");
        lsLKeyValue1.setValue("从未听说过");
        KeyValuePairDto lsLKeyValue2 = new KeyValuePairDto();
        lsLKeyValue2.setKey("2");
        lsLKeyValue2.setValue("在国内曾发生过");
        KeyValuePairDto lsLKeyValue3 = new KeyValuePairDto();
        lsLKeyValue3.setKey("3");
        lsLKeyValue3.setValue("在业内曾发生过");
        KeyValuePairDto lsLKeyValue4 = new KeyValuePairDto();
        lsLKeyValue4.setKey("4");
        lsLKeyValue4.setValue("在公司内发生过");
        KeyValuePairDto lsLKeyValue5 = new KeyValuePairDto();
        lsLKeyValue5.setKey("5");
        lsLKeyValue5.setValue("近一年内发生过");
        lsItemLOptions.add(lsLKeyValue1);
        lsItemLOptions.add(lsLKeyValue2);
        lsItemLOptions.add(lsLKeyValue3);
        lsItemLOptions.add(lsLKeyValue4);
        lsItemLOptions.add(lsLKeyValue5);
        lsItemL.setOptions(lsItemLOptions);
        lsItemL.setPrompt("L—可能性");

        HazardRiskEvaluationOptionsItemDto lsItemS = new HazardRiskEvaluationOptionsItemDto();
        lsItemS.setCode("S");
        lsItemS.setName("S");
        List<KeyValuePairDto> lsItemSOptions = new ArrayList<>();
        KeyValuePairDto lsSKeyValue1 = new KeyValuePairDto();
        lsSKeyValue1.setKey("1");
        lsSKeyValue1.setValue("一般无损伤");
        KeyValuePairDto lsSKeyValue2 = new KeyValuePairDto();
        lsSKeyValue2.setKey("2");
        lsSKeyValue2.setValue("1至2人轻伤");
        KeyValuePairDto lsSKeyValue3 = new KeyValuePairDto();
        lsSKeyValue3.setKey("3");
        lsSKeyValue3.setValue("造成1至2人重伤,3至6人轻伤");
        KeyValuePairDto lsSKeyValue4 = new KeyValuePairDto();
        lsSKeyValue4.setKey("4");
        lsSKeyValue4.setValue("1人死亡,3至6人重伤或严重职业病");
        KeyValuePairDto lsSKeyValue5 = new KeyValuePairDto();
        lsSKeyValue5.setKey("5");
        lsSKeyValue5.setValue("2人以上死亡,7人及以上重伤");
        lsItemSOptions.add(lsSKeyValue1);
        lsItemSOptions.add(lsSKeyValue2);
        lsItemSOptions.add(lsSKeyValue3);
        lsItemSOptions.add(lsSKeyValue4);
        lsItemSOptions.add(lsSKeyValue5);
        lsItemS.setOptions(lsItemSOptions);
        lsItemS.setPrompt("S—后果严重性");

        itemLS.add(lsItemL);
        itemLS.add(lsItemS);
        method2.setOptions(itemLS);
        method2.setLevel1(0);
        method2.setLevel2(4);
        method2.setLevel3(9);
        method2.setLevel4(16);

        //LSC法
        HazardRiskEvaluationMethodDto method3 = new HazardRiskEvaluationMethodDto();
        method3.setMethod(3);
        method3.setName("LEC法");
        List<HazardRiskEvaluationOptionsItemDto> itemLEC = new ArrayList<>();
        HazardRiskEvaluationOptionsItemDto lecItemL = new HazardRiskEvaluationOptionsItemDto();
        lecItemL.setCode("L");
        lecItemL.setName("L");
        List<KeyValuePairDto> lecItemLOptions = new ArrayList<>();
        KeyValuePairDto lecLKeyValue1 = new KeyValuePairDto();
        lecLKeyValue1.setKey("0.1");
        lecLKeyValue1.setValue("实际不可能");
        KeyValuePairDto lecLKeyValue2 = new KeyValuePairDto();
        lecLKeyValue2.setKey("0.2");
        lecLKeyValue2.setValue("极不可能");
        KeyValuePairDto lecLKeyValue3 = new KeyValuePairDto();
        lecLKeyValue3.setKey("0.5");
        lecLKeyValue3.setValue("很不可能,可以设想");
        KeyValuePairDto lecLKeyValue4 = new KeyValuePairDto();
        lecLKeyValue4.setKey("1");
        lecLKeyValue4.setValue("可能性小,完全意外");
        KeyValuePairDto lecLKeyValue5 = new KeyValuePairDto();
        lecLKeyValue5.setKey("3");
        lecLKeyValue5.setValue("可能,但不经常");
        KeyValuePairDto lecLKeyValue6 = new KeyValuePairDto();
        lecLKeyValue6.setKey("6");
        lecLKeyValue6.setValue("相当可能");
        KeyValuePairDto lecLKeyValue7 = new KeyValuePairDto();
        lecLKeyValue7.setKey("10");
        lecLKeyValue7.setValue("完全可以预料");
        lecItemLOptions.add(lecLKeyValue1);
        lecItemLOptions.add(lecLKeyValue2);
        lecItemLOptions.add(lecLKeyValue3);
        lecItemLOptions.add(lecLKeyValue4);
        lecItemLOptions.add(lecLKeyValue5);
        lecItemLOptions.add(lecLKeyValue6);
        lecItemLOptions.add(lecLKeyValue7);
        lecItemL.setOptions(lecItemLOptions);
        lecItemL.setPrompt("L（Likelihood，事故发生的可能性）");

        HazardRiskEvaluationOptionsItemDto lecItemE = new HazardRiskEvaluationOptionsItemDto();
        lecItemE.setCode("E");
        lecItemE.setName("E");
        List<KeyValuePairDto> lecItemEOptions = new ArrayList<>();
        KeyValuePairDto lecEKeyValue1 = new KeyValuePairDto();
        lecEKeyValue1.setKey("0.5");
        lecEKeyValue1.setValue("非常罕见地暴露");
        KeyValuePairDto lecEKeyValue2 = new KeyValuePairDto();
        lecEKeyValue2.setKey("1");
        lecEKeyValue2.setValue("每年几次暴露");
        KeyValuePairDto lecEKeyValue3 = new KeyValuePairDto();
        lecEKeyValue3.setKey("2");
        lecEKeyValue3.setValue("每月一次暴露");
        KeyValuePairDto lecEKeyValue4 = new KeyValuePairDto();
        lecEKeyValue4.setKey("3");
        lecEKeyValue4.setValue("每周一次,或偶尔暴露");
        KeyValuePairDto lecEKeyValue5 = new KeyValuePairDto();
        lecEKeyValue5.setKey("6");
        lecEKeyValue5.setValue("每天工作时间内暴露");
        KeyValuePairDto lecEKeyValue6 = new KeyValuePairDto();
        lecEKeyValue6.setKey("10");
        lecEKeyValue6.setValue("连续暴露");
        lecItemEOptions.add(lecEKeyValue1);
        lecItemEOptions.add(lecEKeyValue2);
        lecItemEOptions.add(lecEKeyValue3);
        lecItemEOptions.add(lecEKeyValue4);
        lecItemEOptions.add(lecEKeyValue5);
        lecItemEOptions.add(lecEKeyValue6);
        lecItemE.setOptions(lecItemEOptions);
        lecItemE.setPrompt("E（Exposure，人员暴露于危险环境中的频繁程度）");

        HazardRiskEvaluationOptionsItemDto lecItemC = new HazardRiskEvaluationOptionsItemDto();
        lecItemC.setCode("C");
        lecItemC.setName("C");
        List<KeyValuePairDto> lecItemCOptions = new ArrayList<>();
        KeyValuePairDto lecCKeyValue1 = new KeyValuePairDto();
        lecCKeyValue1.setKey("1");
        lecCKeyValue1.setValue("引人注目,需要救护");
        KeyValuePairDto lecCKeyValue2 = new KeyValuePairDto();
        lecCKeyValue2.setKey("3");
        lecCKeyValue2.setValue("重大,致残");
        KeyValuePairDto lecCKeyValue3 = new KeyValuePairDto();
        lecCKeyValue3.setKey("7");
        lecCKeyValue3.setValue("严重,重伤");
        KeyValuePairDto lecCKeyValue4 = new KeyValuePairDto();
        lecCKeyValue4.setKey("15");
        lecCKeyValue4.setValue("非常严重,一人死亡");
        KeyValuePairDto lecCKeyValue5 = new KeyValuePairDto();
        lecCKeyValue5.setKey("40");
        lecCKeyValue5.setValue("难,数人死亡");
        KeyValuePairDto lecCKeyValue6 = new KeyValuePairDto();
        lecCKeyValue6.setKey("100");
        lecCKeyValue6.setValue("大灾难,许多人死亡");
        lecItemCOptions.add(lecCKeyValue1);
        lecItemCOptions.add(lecCKeyValue2);
        lecItemCOptions.add(lecCKeyValue3);
        lecItemCOptions.add(lecCKeyValue4);
        lecItemCOptions.add(lecCKeyValue5);
        lecItemCOptions.add(lecCKeyValue6);
        lecItemC.setOptions(lecItemCOptions);
        lecItemC.setPrompt("C（Consequence，一旦发生事故可能造成的后果）");

        itemLEC.add(lecItemL);
        itemLEC.add(lecItemE);
        itemLEC.add(lecItemC);
        method3.setOptions(itemLEC);
        method3.setLevel1(0);
        method3.setLevel2(70);
        method3.setLevel3(160);
        method3.setLevel4(320);

        result.add(method1);
        result.add(method2);
        result.add(method3);
        return result;
    }

    /**
     * 查询危险源台账
     * 
     * @param condition 查询条件
     * @return QueryHazardAccountResultDto
     * @author QuCheng Tech
     * @since 2024/7/16
     */
    @RequestMapping(value = "/account",method = {RequestMethod.GET,RequestMethod.POST})
    public QueryHazardAccountResultDto queryAccount(@RequestBody QueryHazardAccountConditionDto condition) throws QCPromptException {
        
        //1.获取当前用户所属部门ID集合
        String token = request.getHeader(QCAuthConstant.TOKEN_HEADER_KEY);
        List<DeptSimpleDto> depts = getUserValidDepts(token);
        if (CollectionUtils.isEmpty(depts)) throw new QCPromptException("当前用户无有效项目部门信息");
        List<Integer> deptIds = depts.stream().map(DeptSimpleDto::getId).collect(Collectors.toList());
        
        //2.根据部门ids获取当前用户所属组织
        //String orgCode = orgService.getOrgCodeByDeptIds(deptIds);
        //if (StringUtils.isBlank(orgCode)) throw new QCPromptException("当前用户无有效组织信息");
        UacUserInfoDto userInfo = getUserInfo(token);
        String projectCode = userInfo.getProject();
        EhsOrgDto org = orgController.getUserOrgByParam(projectCode);
        if (Objects.isNull(org)) throw new QCPromptException("当前用户无有效组织信息");
        String orgCode = org.getOrgcode();

        //3.定义返回结果项
        QueryHazardAccountResultDto result = null;
       
        //4.判断查询结果显示方法，不同的显示调用不同的方法
        if (condition.getByunit()){
            //4.1 按单元显示查询结果
            result = unitIdentificationRecordService.queryAccountByUnit(condition,deptIds,orgCode);
            
        }else {
            //4.2 按危险源类别显示查询结果
            result = unitIdentificationRecordService.queryAccountByHazardCtg(condition);
        }
        
        //5.返回结果项
        return result;
    }

    /**
     * 修改指定单元指定周期的单元危险源辨识记录状态
     *
     * @param dto 修改条件
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/7/26
     */
    @RequestMapping(value = "/editstatus",method = {RequestMethod.GET,RequestMethod.POST})
    public String editIdentificationStatus(@RequestBody EditUnitHazardStatusDto dto){
        return unitIdentificationRecordService.editIdentificationStatus(dto);
    }

    /**
     * 新增/更新指定单元最新状态信息
     * 
     * @param unitId 单元ID
     * @throws QCPromptException
     * @author QhCheng Tech
     * @since 2024/7/4
     */
    private void addOrUpdateUnitLatestStatus(String unitId) throws QCPromptException {
        //1.查询指定单元危险源辨识记录，统计各数量设置单元最新状态信息
        Integer general1Count = 0x0,major1Count = 0x0,level11Count = 0x0,level12Count = 0x0,level13Count = 0x0,level14Count = 0x0,
                general2Count = 0x0,major2Count = 0x0,level21Count = 0x0,level22Count = 0x0,level23Count = 0x0,level24Count = 0x0;
        List<EhsUnitIdentificationRecord> identificationRecords = unitIdentificationRecordService.getRecordsByUnitId(unitId);
        if (CollectionUtils.isNotEmpty(identificationRecords)){
            for (EhsUnitIdentificationRecord record : identificationRecords){
                //各数量统计
                general1Count += record.getGeneral1();
                major1Count += record.getMajor1();
                level11Count += record.getLevel11();
                level12Count += record.getLevel12();
                level13Count += record.getLevel13();
                level14Count += record.getLevel14();
                general2Count += record.getGeneral2();
                major2Count += record.getMajor2();
                level21Count += record.getLevel21();
                level22Count += record.getLevel22();
                level23Count += record.getLevel23();
                level24Count += record.getLevel24();
            }
        }
        //2.查询指定单元最新状态记录信息，设置更新内容
        EhsUnitLateststatus unitLateststatus = unitLateststatusService.getbyUnitId(unitId);
        boolean unitLateststatusIsExist = true;////记录是否存在，默认存在
        if (unitLateststatus == null){
            unitLateststatusIsExist = false;
            unitLateststatus = new EhsUnitLateststatus();
            unitLateststatus.setUnitid(unitId);
        }
        unitLateststatus.setGeneral1(general1Count);
        unitLateststatus.setMajor1(major1Count);
        unitLateststatus.setLevel11(level11Count);
        unitLateststatus.setLevel12(level12Count);
        unitLateststatus.setLevel13(level13Count);
        unitLateststatus.setLevel14(level14Count);
        unitLateststatus.setGeneral2(general2Count);
        unitLateststatus.setMajor2(major2Count);
        unitLateststatus.setLevel21(level21Count);
        unitLateststatus.setLevel22(level22Count);
        unitLateststatus.setLevel23(level23Count);
        unitLateststatus.setLevel24(level24Count);
        if (unitLateststatusIsExist){
            //更新单元状态记录信息
            unitLateststatusService.updateUnitLatestStatus(unitLateststatus);
        }else{
            //新增单元状态记录信息
            unitLateststatusService.addUnitLatestStatus(unitLateststatus);
        }
    }

    /**
     * 根据token获取用户所在项目中所有有效的部门
     *
     * @param token 用户登录得到的Token
     * @return 部门简要信息集合
     * @author QuCheng Tech
     * @since 2024/6/14
     */
    //public List<DeptSimpleDto> getProjectValidDepts(String token) {
    //    HttpHeaders headers = new HttpHeaders();
    //    headers.add(QCAuthConstant.TOKEN_HEADER_KEY, token);
    //
    //    ServiceInstance service = discoveryClient.getInstances("module-platform").get(0);
    //    String url = "http://" + service.getHost() + ":" + service.getPort() + "/dept/projectvalid";
    //
    //    HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
    //    ParameterizedTypeReference<List<DeptSimpleDto>> responseType = new ParameterizedTypeReference<List<DeptSimpleDto>>() {
    //    };
    //
    //    ResponseEntity<List<DeptSimpleDto>> response = restTemplate.exchange(
    //            url,//获取资源的地址
    //            HttpMethod.GET,
    //            formEntity,
    //            responseType
    //    );
    //    List<DeptSimpleDto> resultDto = response.getBody();
    //    return resultDto;
    //}

    /**
     * 根据token获取用户有效的部门
     *
     * @param token 用户登录得到的Token
     * @return 部门简要信息集合
     * @author QuCheng Tech
     * @since 2024/7/18
     */
    public List<DeptSimpleDto> getUserValidDepts(String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(QCAuthConstant.TOKEN_HEADER_KEY, token);

        ServiceInstance service = discoveryClient.getInstances("module-platform").get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/dept/uservalid";

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<List<DeptSimpleDto>> responseType = new ParameterizedTypeReference<List<DeptSimpleDto>>() {
        };

        ResponseEntity<List<DeptSimpleDto>> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        List<DeptSimpleDto> resultDto = response.getBody();
        return resultDto;
    }

    /**
     * 根据token获取用户信息
     *
     * @param token 用户登录得到的Token
     * @return 用户
     * @author QuCheng Tech
     * @since 2024/7/1
     */
    public UacUserInfoDto getUserInfo(String token) {
        HttpHeaders headers = new HttpHeaders();
        headers.add(QCAuthConstant.TOKEN_HEADER_KEY, token);

        ServiceInstance service = discoveryClient.getInstances("module-platform").get(0);
        String url = "http://" + service.getHost() + ":" + service.getPort() + "/uac/userinfo";

        HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
        ParameterizedTypeReference<UacUserInfoDto> responseType = new ParameterizedTypeReference<UacUserInfoDto>() {
        };

        ResponseEntity<UacUserInfoDto> response = restTemplate.exchange(
                url,//获取资源的地址
                HttpMethod.GET,
                formEntity,
                responseType
        );
        UacUserInfoDto resultDto = response.getBody();

        return resultDto;
    }
}
